package springfox.documentation.swagger.schema;

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.core.annotation.Order;
import springfox.documentation.BeanUtils;
import springfox.documentation.schema.Annotations;
import springfox.documentation.service.AllowableValues;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
import springfox.documentation.swagger.schema.ApiModelProperties;
import springfox.documentation.swagger.schema.ApiModelPropertyPropertyBuilder;

import java.lang.reflect.AnnotatedElement;
import java.util.Optional;


/**
 * 让swagger的@ApiModelProperty#required优先读取JSR303注解
 *
 *
 */
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
public class ApiModelPropertyPropertyBuilderNew extends ApiModelPropertyPropertyBuilder {
    private final DescriptionResolver descriptions;



    public ApiModelPropertyPropertyBuilderNew(DescriptionResolver descriptions) {
        super(descriptions);
        this.descriptions = descriptions;
    }

    @Override
    public void apply(ModelPropertyContext context) {
        Optional<ApiModelProperty> annotation = Optional.empty();
        if (context.getAnnotatedElement().isPresent()) {
            annotation = (Optional) annotation.map(Optional::of).orElse(ApiModelProperties.findApiModePropertyAnnotation((AnnotatedElement) context.getAnnotatedElement().get()));
        }

        if (context.getBeanPropertyDefinition().isPresent()) {
            annotation = (Optional) annotation.map(Optional::of).orElse(Annotations.findPropertyAnnotation((BeanPropertyDefinition) context.getBeanPropertyDefinition().get(), ApiModelProperty.class));
        }

        if (annotation.isPresent()) {
            context.getBuilder().allowableValues((AllowableValues) annotation.map(ApiModelProperties.toAllowableValues()).orElse((AllowableValues) null))
//                    .required((Boolean) annotation.map(ApiModelProperty::required).orElse(false))
                    .readOnly((Boolean) annotation.map(ApiModelProperty::readOnly).orElse(false))
                    .description((String) annotation.map(ApiModelProperties.toDescription(this.descriptions)).orElse((String) null))
                    .isHidden((Boolean) annotation.map(ApiModelProperty::hidden).orElse(false))
                    .type((ResolvedType) annotation.map(ApiModelProperties.toType(context.getResolver())).orElse((ResolvedType) null))
                    .position((Integer) annotation.map(ApiModelProperty::position).orElse(0))
                    .example((String) annotation.map(ApiModelProperties.toExample()).orElse((String) null));


            // 如果  required 已经被其他Plugin设置为true了则就不读取ApiModelProperty的required
            Boolean required = (Boolean) BeanUtils.getFieldValue(context.getBuilder(), "required");
            if (null == required || !required) {
                context.getBuilder().required((Boolean) annotation.map(ApiModelProperty::required).orElse(false));
            }
        }

    }



}
